<?php

/**
 * 短信
 * @author chenshubo
 */
namespace App\Service\Sms;

use App\Service\Qrcode\VerifyImg;
use App\Service\BaseService;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;
use App\Service\AppService\SystemCacheConfigService;

class SendSmsCode extends BaseService
{
    const rdb           = 3;
    const expire        = 5*60;
    const limit         = 10;
    const limit_time    = 5*60;
    const limit_key     = 'visit_key_';
    
    /**
    * 发送短信
    * @param    array $param
    * @access   public
    * @return   array
    */
    public function sendMessage(array $param = [])
    {
        if( empty($param['mobile']) ) {
            return Normal::returnCode(Normal::FAIL,"手机号码不能为空");
        }

        if( empty($param['type']) ) {
            return Normal::returnCode(Normal::FAIL,"类型不能为空");
        }
        
        if( empty($param['uuid']) ) {
            return Normal::returnCode(Normal::FAIL,"唯一标识符uuid不能为空");
        }
        
        if( empty($param['code']) ) {
            return Normal::returnCode(Normal::FAIL,"图形验证码不能为空");
        }
        
        //发送短信之前必须要先经过图形验证码
        $verify_key = $param['uuid'].'_'.$param['type'];
        $res = VerifyImg::instance()->checkQrCode($verify_key,$param['code']);
        if( !$res ) {
            return Normal::returnCode(Normal::FAIL,"图形验证码不正确，请重新输入");
        }
        
        $mobile = $param['mobile'];
        if( !checkPhone($mobile) ) {
            return Normal::returnCode(Normal::FAIL,"手机号码格式不正确");
        }
        
        $sms_code_key = $param['type']."_".$mobile;
        $redis = $this->getRedisObj();
        
        //验证短信是否发送频繁
        if( !$this->visitFrequency(self::limit_key.$sms_code_key, self::limit_time, self::limit) ) {
            return Normal::returnCode(Normal::FAIL,"发送短信频繁，请稍后再试");
        }
        
        //测试环境不发送短信
        $is_production = config('api.APP_ENV');
        if( $is_production ) {
            $sms_code = rand(100000,999999);
            $config   = SystemCacheConfigService::instance()->getCacheInfoBySystemCode('sms');
            if( empty($config) ) {
                return Normal::returnCode(Normal::FAIL,"发送短信失败，短信未配置，请联系相应业务人员处理！");
            }
            
            //检查对应字段
            $fields = ['keyword','sname','spwd','sprdid','api_url'];
            $res    = SystemCacheConfigService::instance()->checkAllowApiColumnsByFields($config,$fields);
            if( $res['code'] != Normal::SUC ) {
                return $res;
            }
            
            $keyword    = $config['keyword'];
            $message    = "【{$keyword}】云仓商城短信验证码【{$sms_code}】,5分钟之内有效，请尽快使用";
            $data = [
                'sname'   => $config['sname'],
                'spwd'    => $config['spwd'],
                'scorpid' => '',
                'sprdid'  => $config['sprdid'],
                'sdst'    => $mobile,
                'smsg'    => $message,
            ];
            $parameter = [
                [
                    'tag'       => 'SmsCode',
                    'uid'       => IdService::instance()->getOtherID(),
                    'url'       => $config['api_url'],
                    'data'      => $data,
                    'method'    => 'post',
                    'format'    => 'form-data',
                    'header'    => []
                ]
            ];
            $resTask = TaskWorker::instance()->addTask($parameter);
            $res = current($resTask);
            $res = json_decode(json_encode(simplexml_load_string($res['response']['result'], 'SimpleXMLElement', LIBXML_NOCDATA)), true);
            if( !isset($res['State']) || $res['State'] != 0 ) {
                return Normal::returnCode(Normal::FAIL,"短信发送失败");
            }
        } else {
            $sms_code = '123456';
        }
        
        $verify_key = implode("_", [$param['mobile'],$param['uuid'],$param['type']]);
        $redis->select(self::rdb);
        $redis->setex($verify_key,self::expire,$sms_code);
        return Normal::returnCode(Normal::SUC,"发送成功");
    }
    
    /**
     * 验证短信验证码是否正确
     * @param array $param
     */
    public function checkSmsCode( $param = [] ) {
        
        if( empty($param['mobile']) ) {
            return Normal::returnCode(Normal::FAIL,"手机号码不能为空");
        }
        
        if( empty($param['type']) ) {
            return Normal::returnCode(Normal::FAIL,"类型不能为空");
        }
        
        if( empty($param['smscode']) ) {
            return Normal::returnCode(Normal::FAIL,"sms_code不能为空");
        }
        
        if( empty($param['uuid']) ) {
            return Normal::returnCode(Normal::FAIL,"uuid不能为空");
        }
        
        $mobile = $param['mobile'];
        if( !checkPhone($mobile) ) {
            return Normal::returnCode(Normal::FAIL,"手机号码格式不正确");
        }
        
        $verify_key = implode("_", [$param['mobile'],$param['uuid'],$param['type']]);
        $redis = $this->getRedisObj();
        $redis->select(self::rdb);
        $cache = $redis->get($verify_key);
        if( empty($cache) ) {
            return Normal::returnCode(Normal::FAIL,"短信验证码已过期，请重新发送");
        }
        
        if( $cache != $param['smscode'] ) {
            return Normal::returnCode(Normal::FAIL,"短信验证码不正确");
        }
        
        return Normal::returnCode(Normal::SUC,"验证通过");
    }

    /**
     * 业务成功之后，删除短信验证码缓存
     * @param unknown $param
     */
    public function delSmsCache($param) 
    {
        if( empty($param['mobile']) ) {
            return Normal::returnCode(Normal::FAIL,"手机号码不能为空");
        }
        
        if( empty($param['type']) ) {
            return Normal::returnCode(Normal::FAIL,"类型不能为空");
        }
        
        if( empty($param['smscode']) ) {
            return Normal::returnCode(Normal::FAIL,"sms_code不能为空");
        }
        
        $mobile = $param['mobile'];
        if( !checkPhone($mobile) ) {
            return Normal::returnCode(Normal::FAIL,"手机号码格式不正确");
        }
        
        $sms_code_key = $param['type']."_".$mobile;
        $redis = $this->getRedisObj();
        $redis->select(self::rdb);
        $redis->del(self::limit_key.$sms_code_key);
        return Normal::returnCode(Normal::SUC,"删除成功");
    }
    
    /**
     * 短信通知支付失败的情况
     * 目前支付失败暂时配置通知:何龙（18190955578）
     */
    public function notifyPayMobileMessage( $message = null,$mobile = '18190955578' )
    {
        $data = [
            'sname'   => config('api.sms.sname'),
            'spwd'    => config('api.sms.spwd'),
            'scorpid' => '',
            'sprdid'  => config('api.sms.sprdid'),
            'sdst'    => $mobile,
            'smsg'    => $message,
        ];
        $parameter = [
            [
                'tag'       => 'SmsCode',
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => 'http://cf.51welink.com/submitdata/Service.asmx/g_Submit',
                'data'      => $data,
                'method'    => 'post',
                'format'    => 'form-data',
                'header'    => []
            ]
        ];
        $resTask = TaskWorker::instance()->addTask($parameter);
        $res = current($resTask);
        $res = json_decode(json_encode(simplexml_load_string($res['response']['result'], 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        if( !isset($res['State']) || $res['State'] != 0 ) {
            return Normal::returnCode(Normal::FAIL,"短信发送失败");
        }
    
        return Normal::returnCode(Normal::SUC,"发送成功");
    }
}